package input

import (
	"fmt"
	"reflect"

	"gitee.com/knowgo/ego/core/function"
)

func parseMap(argType *function.ArgumentTypeInfo, data interface{}, fn parseFn) (reflect.Value, error) {
	var info = argType.TypeInfo
	if data == nil {
		// 数据是 nil ，返回空数组
		return reflect.MakeMap(info.Type), nil
	}
	mp, ok := data.(map[string]interface{})
	if !ok {
		return reflect.ValueOf(nil), fmt.Errorf("cann't parse as map[%s]interface{}", info.KeyTypeName())
	}
	var count int = 0
	var valMap = reflect.MakeMap(info.Type)
	for k, v := range mp {
		path := fmt.Sprintf("%s[%s]", argType.Name, k)
		val, err := fn(path, v, argType.ItemType)
		if err != nil {
			return reflect.MakeMap(info.Type), err
		}

		if info.IsReferenceTypePtr {
			valMap.SetMapIndex(reflect.ValueOf(k), val)
		} else {
			valMap.SetMapIndex(reflect.ValueOf(k), val.Elem())
		}
		count++
	}

	// 验证合法性
	// 只验证 map 元素个数范围
	for _, v := range argType.Validators {
		if err := v.IsValidate(argType.Name, reflect.ValueOf(count)); err != nil {
			return reflect.MakeSlice(info.Type, 0, 0), err
		}
	}

	// 返回 map
	return valMap, nil
}
